package com.systemframework.sys.configuration;

import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.captcha.generator.MathGenerator;
import cn.hutool.captcha.generator.RandomGenerator;
import cn.hutool.core.util.IdUtil;
import com.systemframework.constants.Constants;
import com.systemframework.enums.CaptchaTypeEnum;
import com.systemframework.exception.ResultException;
import com.systemframework.properties.CaptchaProperties;
import com.systemframework.redis.RedisCache;
import com.systemframework.sys.dto.response.CaptchaResponseDTO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.awt.*;
import java.util.concurrent.TimeUnit;

/**
 * @author summer
 * @date 2024-09-24 12:07
 */
@Configuration
@Slf4j
@AllArgsConstructor
public class CaptchaConfiguration {

    private final CaptchaProperties captchaProperties;

    private final RedisCache redisCache;

    public CaptchaResponseDTO captcha(){
        String captchaType = captchaProperties.getType();
        int width = captchaProperties.getWidth();
        int height = captchaProperties.getHeight();
        int interfereCount = captchaProperties.getInterfereCount();
        int codeLength = captchaProperties.getCode().getLength();
        AbstractCaptcha captcha;
        if (CaptchaTypeEnum.CIRCLE.name().equalsIgnoreCase(captchaType)) {
            captcha = CaptchaUtil.createCircleCaptcha(width, height, codeLength, interfereCount);
        } else if (CaptchaTypeEnum.GIF.name().equalsIgnoreCase(captchaType)) {
            captcha = CaptchaUtil.createGifCaptcha(width, height, codeLength);
        } else if (CaptchaTypeEnum.LINE.name().equalsIgnoreCase(captchaType)) {
            captcha = CaptchaUtil.createLineCaptcha(width, height, codeLength, interfereCount);
        } else if (CaptchaTypeEnum.SHEAR.name().equalsIgnoreCase(captchaType)) {
            captcha = CaptchaUtil.createShearCaptcha(width, height, codeLength, interfereCount);
        } else {
            throw new ResultException("Invalid captcha type: " + captchaType);
        }
        captcha.setGenerator(codeGenerator());
        captcha.setTextAlpha(captchaProperties.getTextAlpha());
        captcha.setFont(captchaFont());
        String captchaKey = IdUtil.fastSimpleUUID();
        redisCache.set(Constants.VERIFICATION_CODE + captchaKey, captcha.getCode(),
                captchaProperties.getExpireSeconds(), TimeUnit.SECONDS);
        return CaptchaResponseDTO.builder().captchaValue(captcha.getImageBase64Data()).captchaKey(captchaKey).build();
    }


    @Bean
    public CodeGenerator codeGenerator() {
        String codeType = captchaProperties.getCode().getType();
        int codeLength = captchaProperties.getCode().getLength();
        if ("math".equalsIgnoreCase(codeType)) {
            return new MathGenerator(codeLength);
        } else if ("random".equalsIgnoreCase(codeType)) {
            return new RandomGenerator(codeLength);
        } else {
            throw new ResultException("Invalid captcha codegen type: " + codeType);
        }
    }

    /**
     * 验证码字体
     */
    @Bean
    public Font captchaFont() {
        String fontName = captchaProperties.getFont().getName();
        int fontSize = captchaProperties.getFont().getSize();
        int fontWight = captchaProperties.getFont().getWeight();
        return new Font(fontName, fontWight, fontSize);
    }

}
